
var sendInterface = require('../command/send.js')
var cmd = require('../command/command.js')

var app = getApp()
var txdu = app.globalData.mtxduuid.toUpperCase()
var rxdu = app.globalData.mrxduuid.toUpperCase()
var serviceu = app.globalData.mserviceuuid.toUpperCase()

var updateCallBack;

function ab2Str(arrayBuffer){
  let unit8Arr = new Uint8Array(arrayBuffer);
  let encodedString = String.fromCharCode.apply(null, unit8Arr);
  return encodedString
}

//蓝牙重连
let fns = {
  reconnection(succ,fail){
      wx.openBluetoothAdapter({
        success :(res) => {
          wx.createBLEConnection({
              deviceId : app.globalData.deviceId ,
              success : (res) => {
                  fns.searchServices(() => {
                      fns.serachCharacteristics(succ,fail)
                  },fail)
              },
              fail : fail
          })
        },
        fail : fail
      })
      
  }, 
  searchServices(succ,fail){
      wx.getBLEDeviceServices({
          deviceId : app.globalData.deviceId,
          success : succ,
          fail : fail
      })
  },
  serachCharacteristics(succ,fail){
       wx.getBLEDeviceCharacteristics({
          deviceId : app.globalData.deviceId,
          serviceId : app.globalData.serviceId,
          success : succ,
          fail : fail
      })
  },
  onBLEConnectionStateChange(res){
   // 该方法回调中可以用于处理连接意外断开等异常情况
   console.warn(`device ${res.deviceId} state has changed, connected: ${res.connected}`)
                  
   //重连
   if(res.connected === false){
     app.globalData.connected = false
     var reconnectId = setInterval(()=>{
       fns.reconnection((succ) => {
         console.log("重连成功，可以调用 wx.writeBLECharacteristicValue")
         app.globalData.connected = true
        
          wx.notifyBLECharacteristicValueChange({  //开启通知
            deviceId:app.globalData.deviceId,
            serviceId:app.globalData.serviceId,
            characteristicId: rxdu,
            state: true, 
            success(res) {
              console.warn('notifyBLECharacteristicValueChange success', res.errMsg)
              console.log("连接成功")
              app.globalData.connected = true

              // receive.onRecevive() //监听
              if(app.globalData.isUpdateting == true){
                onUpdateReceive(updateCallBack) //更新监听
              }else{
                onRecevive() //开启正常的监听流程
              }
              
              wx.offBLEConnectionStateChange()
              wx.onBLEConnectionStateChange(fns.onBLEConnectionStateChange)
            }
          })
       },(err) => {
         if(app.globalData.connected == true){
           clearInterval(reconnectId)
           return
         }
         console.log("err：",err)
       });
     }, 250)
   }else{
     app.globalData.connected = true
   }
  }
}

function bluetoothInit(callback){
  app.globalData.connection = false
  app.readSetting()
  var device = app.globalData.ble_device
  app.globalData.deviceId = device.deviceId
  var deviceId = app.globalData.deviceId
  console.log("bluetoothInit----->","正在连接...")
  wx.createBLEConnection({
    deviceId,
    success: (res) => {
      getBLEDeviceServices(deviceId, callback)
    }
  })
}

function getBLEDeviceServices(deviceId, callback){
  wx.getBLEDeviceServices({
    deviceId,
    success: (res) => {
      var isService = false
      console.log("service size = ", res.services.length)
      for (let i = 0; i < res.services.length; i++) {
        if (serviceu == res.services[i].uuid){
          isService = true
          console.log("获取特征值")
          getBLEDeviceCharacteristics(deviceId, res.services[i].uuid, callback)
          }
      }
      if (!isService){ //没有找到服务
        console.log("UUID错误")
      }
    }
  })
}

function getBLEDeviceCharacteristics(deviceId, serviceId, callback) {
  var connectSuc = false
  wx.getBLEDeviceCharacteristics({
    deviceId,
    serviceId,
    success: (res) => {
      var ismy_service = false
      console.log("compute ", serviceId, serviceu)
      if (serviceId == serviceu) {
        ismy_service = true
        console.warn("this is my service ")
      }
      console.log('getBLEDeviceCharacteristics success', res.characteristics)
      for (let i = 0; i < res.characteristics.length; i++) {
        let item = res.characteristics[i]
        if (ismy_service){
          console.log("-----------------------")
        }
        console.log("this properties = ", item.properties)
        if (item.properties.read) {
          console.log("[Read]", item.uuid)
          wx.readBLECharacteristicValue({
            deviceId,
            serviceId,
            characteristicId: item.uuid,
          })
        }
        if (item.properties.write) {
          console.log("[Write]",item.uuid)
          app.globalData.deviceId = deviceId
          if (ismy_service && (txdu == item.uuid)){
            console.warn("find write uuid  ready to ", item.uuid)
            app.globalData.serviceId = serviceId,
            app.globalData.characteristicId = item.uuid
            callback(true)
          }
        }
        if (item.properties.notify || item.properties.indicate) {
          console.log("[Notify]", item.uuid)
          if (ismy_service && (rxdu == item.uuid)){
            console.warn("find notity uuid try enablec....", item.uuid)
            wx.notifyBLECharacteristicValueChange({  //开启通知
              deviceId,
              serviceId,
              characteristicId: item.uuid,
              state: true, 
              success(res) {
                console.warn('notifyBLECharacteristicValueChange success', res.errMsg)
                console.log("连接成功")
                app.globalData.connected = true
                
                onRecevive() //监听

                wx.offBLEConnectionStateChange()
                wx.onBLEConnectionStateChange(fns.onBLEConnectionStateChange)
              }
            })
          }
        }
      }
    },
    fail(res) {
      console.error('getBLEDeviceCharacteristics', res)
    }
  })
 }

 const senderVector = [];
 function send(sendContents){
     
  if(app.globalData.connected == false)
     return

  senderVector.push(sendContents)
   setTimeout(()=>{
    var contents = senderVector.shift()
    contents += "/r"
    sendInterface.onSend(contents)
    console.log("发送: ", contents)
    // cmd.saveSendMessageText(sendContents)
   }, (senderVector.length) * 50)
 }

 function onRecevive(){
  wx.onBLECharacteristicValueChange((characteristic) => {
    if (rxdu != characteristic.characteristicId){
      console.error("no same : ", rxdu, characteristic.characteristicId)
      return
    }
    var recStr = ab2Str(characteristic.value)
    console.warn("RXlen: ", recStr.length, "recstr: ", recStr, characteristic.characteristicId)

    if(recStr.substring(2, 8) == "READYV"){ //收到这个指令需要直接跳转到更新界面
      console.warn("跳转更新程序")
      app.globalData.isReStartUpdate = true
      app.globalData.restartUpdateVertion = recStr.substring(7, 11)
      // wx.navigateTo({
      //   url: 'pages/device/update/update',
      // })
      return
    }
    var value = cmd.getReceiveValue(recStr)
    if(value != null){
      app.globalData.isDataChanged = true
    }

    cmd.saveRecMessageText(recStr)
    console.log("接收：", recStr, value)
  })
}

function closeReceive(){
  wx.offBLECharacteristicValueChange()
}

function onUpdateReceive(callback){
  updateCallBack = callback
  wx.onBLECharacteristicValueChange((characteristic) => {
    if (rxdu != characteristic.characteristicId){
      console.error("no same : ", rxdu, characteristic.characteristicId)
      return
    }
    var recStr = ab2Str(characteristic.value)
    console.warn("RXlen: ", recStr.length, "recstr: ", recStr, characteristic.characteristicId)

    // cmd.saveRecMessageText("更新固件返回：" + recStr)
    // console.log("更新固件返回：", recStr, value)

    //##READYV000&025B**
    //##RECEIV001&xxxx**
    //##RESTAR001&xxxx**
    // cmd.checkCode(recStr)
    const nextCode = "RECEIV"
    const retryCode = "RESTAR"
    // 0, 1, 2, 3
    if(recStr.substring(2, 8) == nextCode){ //next
      callback(0, recStr.substring(8, 11))
    } else if(recStr.substring(2, 8) == retryCode){ //retry
      callback(1, recStr.substring(8, 11))
    } else if(recStr.substring(2, 8) == "READYV"){ //从头发送
      callback(2 , recStr.substring(7, 11))
    } else if(recStr.substring(2, 7) == "READY"){ //开始发送一包
      callback(0 , recStr.substring(7, 10))
    } else if(recStr.substring(2, 7) == "0018R"){ //查询版本号
      callback(3, recStr.substring(7, 11).toUpperCase())
    }
  })
}

 module.exports = {
  bluetoothInit: bluetoothInit,
  send : send,
  onRecevive: onRecevive,
  closeReceive: closeReceive,
  onUpdateReceive: onUpdateReceive,
  reConnection : fns.reconnection
}